/*
 * The thread Data Access Object, it handles all database transactions between the front end and the database.
 */
package airport.forum.dao;
 
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;

//import airport.forum.pojo.Forum;
//import airport.forum.pojo.Forum;
import airport.forum.pojo.Thread;
import airport.forum.pojo.Post;
//threaddao
@SuppressWarnings("deprecation")
public class ThreadDAO {
	//test push
	private static SessionFactory factory = new AnnotationConfiguration().configure().addAnnotatedClass(Thread.class).addPackage("com.xyz").buildSessionFactory(); 
	
	//adds the given post to the given thread
	public void addPostToThread(Post post, Long threadId) {
		try {
			Session session = factory.openSession();
			Transaction tx = null;
			try {
				System.out.println("***<ThreadDAO>:addPostToThread***");
				tx = session.beginTransaction();
				Thread thread = (Thread) session.load(Thread.class, threadId);
				System.out.println("Going to add post");
				thread.addPost(post);
				System.out.println("After post");
				session.update(thread);
				tx.commit();
				System.out.println("---<ThreadDAO>:addPostToThread---");
			} 
			catch (HibernateException e) {
				if (tx!=null) 
	        		 tx.rollback();
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) { 
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
        }
	}
	
	//retrieves a set containing all the posts of a given thread
	//for display when someone clicks a thread
	public Set<Post> getAllPostsFromThread(Long threadId) {
		Set<Post> posts = null;
		try {
			Session session = factory.openSession();
			try {
				System.out.println("***<ThreadDAO>:getAllPostsFromThread***");
				Thread thread = (Thread) session.load(Thread.class, threadId);
				posts = thread.getPostlist();
				System.out.println("post number: "+posts.size());
				
				//if (posts != null) {
				//	Iterator<Post> it = threads.iterator();
				//	while (it.hasNext()) {
				//		Post post = it.next();
				//		System.out.println(post.getPostId());
				//	}					
				//}
				System.out.println("---<ThreadDAO>:getAllPostsFromThread---");
			}
			catch (HibernateException e) {
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) { 
	         System.err.println("Failed to create sessionFactory object." + ex);
	         throw new ExceptionInInitializerError(ex);
	    }
		return posts;
	}
	
	//gets posts in linked list for display on a page
	//the posts per page can be specified in the method parameters
	public LinkedList<Post> getPostsByPage (Long threadId, int page, int pageSize) {
		LinkedList <Post> posts = null;
		try {
			Session session =  factory.openSession();
			try {
				System.out.println("***<ThreadDAO>:getPostsByPage***");
				Thread thread = (Thread) session.load(Thread.class, threadId);
				Set <Post> allPosts = thread.getPostlist();
				int size = allPosts.size();
				System.out.println("post number: "+size);
				int lastPageLen = size%pageSize;
				int numPage = 0;
				if (lastPageLen == 0) {
					numPage = size/pageSize;
				}
				else {
					numPage = size/pageSize +1;
				}
				System.out.println("The posts can be display in "+numPage + " pages.");
				if (page > numPage ) {
					System.out.println("!!!Invalid Parameter: page. ");
				}
				else {
					int start = (page - 1) * pageSize;
					System.out.println("start page: "+ start);
					Iterator<Post> it = allPosts.iterator();
					for (int i = 0; i < start; i ++) {
						System.out.println("Go to the right page to start");
						if (it.hasNext()) {
							it.next();
						}
					}
					posts =  new LinkedList<Post>();
					System.out.println("Going to add posts to linkedlist.");
					if (page != numPage) {
						for (int j = 0; j < pageSize; j++) {
							if (it.hasNext()) {
								Post post = it.next();
								System.out.println("current post id: "+ thread.getThreadId());
								posts.add(post);
							}
						}
					}
					else {
						if (lastPageLen == 0)
							lastPageLen = pageSize;
						for (int j = 0; j < lastPageLen; j++) {
							if (it.hasNext()) {
								Post post = it.next();
								System.out.println("current post id: "+ thread.getThreadId());
								posts.add(post);
							}
						}
					}
				}
				System.out.println("---<ThreadDAO>:getPostsByPage---");
			}
			catch (HibernateException e) {
				e.printStackTrace();
			}
			finally {
				session.close();
			}
		}
		catch (Throwable ex) {
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
		return posts;
	}
	
	//retrieves a thread object via its id
	@SuppressWarnings("unchecked")
	public Thread getThread (long id) {
		Thread thread = null;
		System.out.println("get thread");
		try {
	         Session session = factory.openSession();
	         try {
	        	 System.out.println("start query");
	        	 String hql = "FROM Thread T where T.threadId = '"+id+"'";
	        	 System.out.println(hql);
	        	 Query query = session.createQuery(hql);
	        	 List<Thread> results = query.list();
	        	 System.out.println("thread number:"+results.size());
	        	 if (results.size() != 0) {
	        		 thread = results.get(0);
	        		 System.out.println("thread found!"); 
	        	 	}
	        	 else
	        	 	System.out.println("no thread found");
	        	 } 
	         catch (HibernateException e) {
	        	 e.printStackTrace();
	         } 
	         finally {
	            session.close(); 
	         }
	      } catch (Throwable ex) { 
	         System.err.println("Failed to create sessionFactory object." + ex);
	         throw new ExceptionInInitializerError(ex);
	      }
		return thread;
	}
}
